/*
 *       This file is part of VFC.
 *
 *        VFC is free software: you can redistribute it and/or modify
 *        it under the terms of the GNU General Public License as published by
 *        the Free Software Foundation, either version 3 of the License, or
 *        (at your option) any later version.
 *
 *        VFC is distributed in the hope that it will be useful,
 *        but WITHOUT ANY WARRANTY; without even the implied warranty of
 *        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *        GNU General Public License for more details.
 *
 *        You should have received a copy of the GNU General Public License
 *        along with VFC.  If not, see <http://www.gnu.org/licenses/>.
 */


using System;
using System.Collections.Generic;
using System.Text;

namespace VFC.Nes.Cpu.Opcode.Unofficial
{
    class Immidiate
    {
        private static int tmp = 0, tmp2 = 0, tmp3 = 0;

        public static void AAC()
        {
            tmp = Cpu.Register.A;
            tmp2 = Cpu.Core.Param1;

            tmp3 = tmp & tmp2;
            Flags.CheckForNegativeFlag(tmp3);
            if ((tmp3 & 0x80) == 0x80)
            {
                Cpu.Register.SetCarryFlag();
            }
            Cpu.Register.A = tmp3 & 0xff;
            Cpu.Register.PC += Cpu.Core.Size[Cpu.Core._Opcode_];
        }

        public static void ARR()
        {
            tmp = Cpu.Register.A;
            tmp2 = Cpu.Core.Param1;

            tmp3 = tmp & tmp2;
            if ((tmp3 & 0x01) == 0x01)
            {
                tmp3 >>= 1;
                tmp3 |= 0x80;
            }
            else
            {
                tmp3 >>= 1;
            }

            if ((tmp3 & 0x40) == 0x40 && (tmp3 & 0x20) == 0x20)
            {
                Cpu.Register.SetCarryFlag();
                Cpu.Register.ClearOverflowFlag();
            }
            else if ((tmp3 & 0x40) != 0x40 && (tmp3 & 0x20) != 0x20)
            {
                Cpu.Register.ClearCarryFlag();
                Cpu.Register.ClearOverflowFlag();
            }
            else if ((tmp3 & 0x40) != 0x40 && (tmp3 & 0x20) == 0x20)
            {
                Cpu.Register.ClearCarryFlag();
                Cpu.Register.SetOverflowFlag();
            }
            else if ((tmp3 & 0x40) == 0x40 && (tmp3 & 0x20) != 0x20)
            {
                Cpu.Register.SetCarryFlag();
                Cpu.Register.SetOverflowFlag();
            }

            Cpu.Register.A = tmp3 & 0xff;
            Cpu.Register.PC += Cpu.Core.Size[Cpu.Core._Opcode_];

        }

        public static void ASR()
        {
            tmp = Cpu.Register.A;
            tmp2 = Cpu.Core.Param1;

            tmp &= tmp2;
            tmp >>= 1;
            Cpu.Flags.CheckForNegativeFlag(tmp);
            Cpu.Flags.CheckForZeroFlag(tmp);
            Cpu.Flags.CheckForCarryFlag(tmp);
            Cpu.Register.A = tmp;
            Cpu.Register.PC += Cpu.Core.Size[Cpu.Core._Opcode_];
        }

        public static void ATX()
        {
            Console.WriteLine("ERROR: Unimplemented Opcode $" + Cpu.Core._Opcode_.ToString("X2") + " at $" + Cpu.Register.PC.ToString("X2"));
            Emu.EmuCore.Stop();
        }

        public static void AXS()
        {
            Console.WriteLine("ERROR: Unimplemented Opcode $" + Cpu.Core._Opcode_.ToString("X2") + " at $" + Cpu.Register.PC.ToString("X2"));
            Emu.EmuCore.Stop();
        }

        public static void DOP()
        {
            Console.WriteLine("ERROR: Unimplemented Opcode $" + Cpu.Core._Opcode_.ToString("X2") + " at $" + Cpu.Register.PC.ToString("X2"));
            Emu.EmuCore.Stop();
        }

        public static void SBC()
        {
            Console.WriteLine("ERROR: Unimplemented Opcode $" + Cpu.Core._Opcode_.ToString("X2") + " at $" + Cpu.Register.PC.ToString("X2"));
            Emu.EmuCore.Stop();
        }

        public static void XAA()
        {
            Console.WriteLine("ERROR: Unimplemented Opcode $" + Cpu.Core._Opcode_.ToString("X2") + " at $" + Cpu.Register.PC.ToString("X2"));
            Emu.EmuCore.Stop();
        }
    }
}
